在nodejs中使用express和express

您所在的位置:网站首页 session 实现 在nodejs中使用express和express

在nodejs中使用express和express

2024-02-22 18:30| 来源: 网络整理| 查看: 265

什么是session

web是基于 HTTP 协议的, 而HTTP 是一种无状态协议,也就是说在每个请求和响应结束时,客户端和服务器不知道对方是谁。

这就是session的用处,session也叫做会话。允许服务器在多个请求之间维护用户的数据和状态,从而实现用户身份验证、保持登录状态、存储用户信息等功能。

session的工作机制 客户端(浏览器)发送首次请求到服务器。 服务器收到请求,发现客户端没有提供会话ID(缺少一个值为 session-id 的cookie)。 服务器创建一个新的会话,生成一个唯一的会话ID,并将其存储在 session-id cookie 中,并将会话数据保存在后端存储中(例如内存、数据库等)。 服务器将会话ID作为响应的 Set-Cookie 头部发送回客户端,客户端浏览器会存储这个会话ID。 从此以后,客户端的每个请求都会附带这个会话ID的 session-id cookie。 服务器根据收到的会话ID,从后端存储中查找相应的会话数据,以恢复用户的会话状态。 session和cookie的区别

cookie 是存储在浏览器中的键值对。浏览器会吧对应域名下面的 cookie 附加到发送到服务器的每个 HTTP 请求。

在 cookie 中,无法存储大量数据,cookie的大小通常受到浏览器对单个cookie大小和每个域名的cookie总数的限制,一般较小。最好不要吧敏感的数据比如用户信息存在cookie中。

session数据存储在服务器端,一般会放在数据库里面。因此,它可以容纳更大量的数据。session是通过在客户端cookie中存储会话ID,服务器使用这个ID查找对应的会话数据来实现。

开发环境设置

初始化package.json

$ npm init –y

安装express-session

在nodejs中管理session(会话),需要使用express-session这个中间件,可以使用下面的命令安装这个模块:

$ npm i express-session

安装express

要在 Node.js 中使用 express-session 模块设置会话,还需要安装 Express 模块:

$ npm i express

使用express-session //app.js const express = require('express') const session = require('express-session') const app = express() app.use(session({ secret: 'Your_Secret_Key', resave: false, })) app.get('/',(req,res) => { res.send("hello"); }); app.listen(3000, () => { console.log('Server is running at port 3000') })

使用app.use(session(options))就可以使用这个中间件,其中:

secret 是一个密钥,用来签名session-id

resave bool类型,默认为true,用于指定是否在每次请求时重新保存会话,即使会话在请求过程中从未被修改过。比如客户端向服务器发出两个并行请求,当第二请求结束时,对第一请求的会话所做的修改可能会被覆盖。

执行$node app.js之后,我们使用curl命令来测试这个程序

$ curl -i localhost:3000

Untitled.png

设置cookie的属性

上面例子可以看到session中间件帮我们设置了一个cookie,cookie的默认key为:connect.sid,

可以使用name字段设置cookie的key

app.use(session({ secret: 'Your_Secret_Key', resave: false, name: 'mycookie' }))

image.png

还可以配置cookie的其他属性,如maxAge,secure等

//过期时间为一天 const oneDay = 1000 * 60 * 60 * 24; app.use(session({ secret: 'Your_Secret_Key', resave: false, cookie: { maxAge: oneDay, HttpOnly: true, secure: false}, name: 'mycookie' }))

Untitled 2.png

使用session记录页面访问次数

上面的例子没有什么用处,这里我们来实现一个记录用户访问页面次数的例子:

app.get('/', function (req, res, next) { if (req.session.views) { req.session.views++ res.send('views: ' + req.session.views) } else { req.session.views = 1 res.end('welcome to the session demo. please curl again!') } })

当客户端第一次请求时,我们会给req.session写入一个views属性,当客户端再次发起请求时,会吧views加1,然后返回给客户端

使用curl请求:

$ curl -i localhost:3000

Untitled 3.png

可以看到,响应的是'welcome to the session demo. please curl again!'

使用curl携带上一次的cookie再次请求:

$ curl -i -b "mycookie=s%3A_lsIhF-wH-IwuiUBeKcpqq_KIv1JVfFW.PVY28Bj0DhABROPOZM9h%2BY4gcbb7MVEyYqMu8lH73LI" localhost:3000

Untitled 4.png

再次请求之后会响应用户访问的次数

使用session实现登陆退出功能 实现登录页面

登录页面是这样的:

Untitled 5.png login.html代码如下:

Login body { font-family: Arial, sans-serif; background-color: #f2f2f2; margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; } .login-container { background-color: #fff; border-radius: 5px; padding: 20px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); width: 300px; } .login-container h1 { text-align: center; margin-bottom: 20px; } .login-form label { display: block; margin-bottom: 10px; } .login-form input[type="text"], .login-form input[type="password"] { width: 100%; border: 1px solid #ccc; border-radius: 3px; } .login-form input[type="submit"] { background-color: #007bff; color: #fff; border: none; padding: 10px; border-radius: 3px; width: 100%; cursor: pointer; } .login-form input[type="submit"]:hover { background-color: #0056b3; } Login Form Username: Password:

这个HTML登录表单,会使用POST方法将用户名和密码提交到服务器上的/login路由

处理根路由请求 app.get('/', function (req, res, next) { if (req.session.userid) { res.send("欢迎 点击退出"); } else { res.sendFile('./login.html', { root: __dirname }) } })

跟路由请求会判断session里面是否有userid,如果有,则显示退出,否则显示登录页面

处理/login登录请求 //使用urlencoded中间件解析post请求 app.use(express.urlencoded()); const myusername = 'admin'; const mypassword = 'admin'; app.post('/login', (req, res) => { if (req.body.username === myusername && req.body.password === mypassword) { **req.session.userid = req.body.username;** console.log(req.session) res.send(`登录成功 点击退出`); } else { res.send('不合理的 username 或 password'); } })

这里我们用到了express.urlencoded中间件,这个中间件可以帮我们解析POST请求,并吧请求体的字段放在req.body里面

然后我们处理login请求,为了演示我们吧用户名和密码写死,用户名密码匹配之后,我们会吧username写入session

运行一下程序:

node app.js

然后访问:http://localhost:3000/

输入用户名和密码登录之后可以看到登录成功,并且有了cookie,再次刷新页面,还会显示登录成功的页面,因为用户的信息已经被放在session里面

Untitled 6.png

然后会到命令行可以看到打印的session如下:

Untitled 7.png

实现/logout退出接口 app.get('/logout',(req,res) => { req.session.destroy(); res.redirect('/'); });

我们直接调用session的destroy方法就可以实现退出

res.redirect是重定向功能,通过它会向用户返回一个 302 状态,通知 浏览器转向相应页面。

点击退出登录,我们就会回到首页,并且显示了登录页面

问题

可以看出登入和登出仅仅是 req.session.userid 变量的标记,非常简单。但这会不会有安全性问题呢?是不会的,因为这个变量只有服务端才能访问到,只要不是黑客攻破了整个服务器,无法从外部改动

完整代码地址:

github.com/AC-greener/…

总结

这篇文章我们学会了使用session来管理会话,但是还有一些不足,我们的session是存在服务器内存的,当重启服务器时,session就没了,或着当有多台服务器时,会话状态也会出现不同步,所以一般会使用MongoDB或者Redis来存储会话,下一篇文章我们会使用到MongoDB~

self-info.png



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3